package model;

import view.client.Console;
import view.client.Decode;
import view.client.Frame;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Hearer implements Runnable {

    private String name;
    private Socket socket;
    private ObjectInputStream in;
    private ObjectOutputStream out;
    private boolean initialized;
    private boolean running;
    private Thread thread;
    private Console console;

    public Hearer(Socket socket, ObjectInputStream in, ObjectOutputStream out, String name) throws Exception {
        this.setName(name);
        initialized = false;
        running = false;
        this.socket = socket;
        this.in = in;
        this.out = out;
        open();
    }

    public void open() throws Exception {
        try {
            initialized = true;
        } catch (Exception e) {
            System.out.println(e);
            close();
            throw e;
        }
    }

    public void addFrame(Frame viewCliente) {
        this.console = viewCliente.getConsole();
    }

    public void close() {
        if (in != null) {
            try {
                in.close();
            } catch (Exception e) {
                System.out.println(e);
            }
        }
        if (out != null) {
            try {
                out.close();
            } catch (Exception e) {
                System.out.println(e);
            }
        }
        if (socket != null) {
            try {
                socket.close();
            } catch (Exception e) {
                System.out.println(e);
            }
        }
        in = null;
        out = null;
        socket = null;
        initialized = false;
        running = false;
        thread = null;
    }

    public void start() {
        if (!initialized || running) {
            return;
        }
        running = true;
        thread = new Thread(this);
        thread.start();
    }

    public void stop() throws Exception {
        running = false;
        if (thread != null) {
            thread.join();
        }
    }

    public boolean isRunning() {
        return running;
    }

    public void send(Object objeto) {
        //SerializedObject newMsg = new Message(name+": "+mensagem);
        try {
            out.writeObject(objeto);
            out.flush();
            out.reset();
        } catch (IOException e) {
            System.out.println("Erro ao conectar com servidor");
            close();
        }
    }

    @Override
    public void run() {
        Decode dc;
        while (running) {
            try {
                socket.setSoTimeout(2500);
                Object inputServer = in.readObject();
                if (inputServer == null) {
                    break;
                }
                //msg = (Message) inputServer;
                dc = new Decode(console, inputServer);
                //dc.run(console);
            } catch (SocketTimeoutException e) {
                //ignorar
            } catch(SocketException e){
                //Logger.getLogger(Hearer.class.getName()).log(Level.SEVERE, null, e);
                System.out.println("Fechando cliente...");
            }
            catch (Exception e) {
                Logger.getLogger(Hearer.class.getName()).log(Level.SEVERE, null, e);
                System.out.println(e);
                close();
                console.outputText("Deu merda");
                break;
            }
        }
        close();

    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}
